package stdio.costa.imoca.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@Entity
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@NamedQueries({
		@NamedQuery(name = "Postcard.readyToPreview", query = "from Postcard p where p.preview is null " + "and p.template is not null "
				+ "and p.payment is not null " + "and p.photo is not null " + "and p.wish is not null " + "and p.address.whom is not null "
				+ "and p.address.postcode is not null " + "and (p.address.province is not null or p.address.city is not null) "
				+ "and p.address.detail is not null"),
		@NamedQuery(name = "Postcard.readyToPrint", query = "from Postcard p where p.preview is not null and p.printedPreview is null"),
		@NamedQuery(name = "Postcard.findCloudReadyPreviews", query = "select p.preview from Postcard p where "
				+ "p.printedPreview is not null " + "and (p.preview.front.data is not null or p.preview.back.data is not null)") })
public class Postcard extends UuidEntity implements Serializable {

	private static final long serialVersionUID = -3402866065680979605L;

	@ManyToOne
	private Image photo;

	@ManyToOne
	private Image wish;

	@ManyToMany(fetch = FetchType.EAGER)
	private List<Image> postmarks;

	@OneToOne(cascade = CascadeType.ALL)
	private Address address = new Address();

	@ManyToOne(fetch = FetchType.EAGER)
	private PostcardTemplate template;

	@ManyToOne
	private Payment payment;

	@OneToOne
	private Preview preview;

	@ManyToOne
	@XmlTransient
	private Preview printedPreview;

	@ManyToOne
	@XmlTransient
	private MocaUser owner;

	public Postcard() {
	}

	public Postcard(Image photo, Image wish, Address address, List<Image> postmarks, PostcardTemplate template) {
		this.photo = photo;
		this.wish = wish;
		this.address = address;
		this.template = template;
		this.postmarks = postmarks;
	}

	public void clearLocalStorage() {
		photo.clearLocalStorage();
		wish.clearLocalStorage();
	}

	public void addPostmarks(Image... postmarks) {
		for (Image postmark : postmarks) {
			getPostmarks().add(postmark);
		}
	}

	public Image getPhoto() {
		return photo;
	}

	public void setPhoto(Image photo) {
		this.photo = photo;
	}

	public Image getWish() {
		return wish;
	}

	public void setWish(Image wish) {
		this.wish = wish;
	}

	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	public PostcardTemplate getTemplate() {
		return template;
	}

	public void setTemplate(PostcardTemplate template) {
		this.template = template;
	}

	public Payment getPayment() {
		return payment;
	}

	public void setPayment(Payment payment) {
		this.payment = payment;
	}

	public Preview getPreview() {
		return preview;
	}

	public void setPreview(Preview preview) {
		this.preview = preview;
	}

	public Preview getPrintedPreview() {
		return printedPreview;
	}

	public void setPrintedPreview(Preview printedPreview) {
		this.printedPreview = printedPreview;
	}

	public MocaUser getOwner() {
		return owner;
	}

	public void setOwner(MocaUser owner) {
		this.owner = owner;
	}

	public List<Image> getPostmarks() {
		if (postmarks == null) {
			postmarks = new ArrayList<Image>();
		}
		return postmarks;
	}

	public void setPostmarks(List<Image> postmarks) {
		this.postmarks = postmarks;
	}

	public boolean isReadyToMake() {
		return address.hasBeenCompleted() && photo != null && wish != null && template != null && payment != null
				&& photo.getData() != null && wish.getData() != null;
	}
}
